package org.smart4j.framework.common.helper;

import com.google.common.base.Function;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.smart4j.framework.common.util.ReflectionUtil;

import javax.annotation.Nullable;
import java.util.Map;
import java.util.Set;

/**
 * Bean助手类
 *
 * @author YooLin1c
 * @version 1.0.0
 * @since 2018-01-30 18:00
 */
@Slf4j
public final class BeanHelper {
    /**
     * Bean容器：存放Bean类与Bean实例的关系映射集合
     */
    private static final Map<Class<?>, Object> BEAN_MAP;

    static {
        //获取所有Bean类（@Controller+@Service注解的类）
        Set<Class<?>> beanClassSet = ClassHelper.getBeanClassSet();
        //通过反射创建每个Bean类的对象并将Bean类与Bean实例的关系映射存储至Map集合中
        BEAN_MAP = Maps.asMap(beanClassSet, new Function<Class<?>, Object>() {
            @Nullable
            @Override
            public Object apply(@Nullable Class<?> clazz) {
                return ReflectionUtil.newInstance(clazz);
            }
        });
    }

    /**
     * 获取Bean容器
     *
     * @return Bean容器
     */
    public static Map<Class<?>, Object> getBeanMap() {
        return BEAN_MAP;
    }

    /**
     * 获取指定类的Bean实例
     *
     * @param clazz 指定类
     * @param <T>   指定类的泛型
     * @return Bean实例
     */
    @SuppressWarnings("unchecked")
    public static <T> T getBean(Class<?> clazz) {
        if (!BEAN_MAP.containsKey(clazz)) {
            throw new RuntimeException("can't not get bean by class : ".concat(clazz.getName()));
        }
        return (T) BEAN_MAP.get(clazz);
    }

    /**
     * 向Bean容器添加Bean
     *
     * @param clazz    Bean类
     * @param instance Bean对象
     */
    public static void addBean(Class<?> clazz, Object instance) {
        BEAN_MAP.put(clazz, instance);
    }
}
